package service

import (
	"kubernate-server/conf"
	"net/http"

	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"

	"github.com/gin-gonic/gin"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

/**
 * Author: 张文进
 * Description: daemonsets增删改查
 * Date: 2025-09-28
 */

type DaemonSetService struct {
}

// 定义全局的结构体类型，供多个函数使用
type DaemonSetRequest struct {
	Name   string            `json:"name" binding:"required"`
	Labels map[string]string `json:"labels"`
	Image  string            `json:"image" binding:"required"`
	Port   int32             `json:"port"`
}

/*
*	获取DaemonSet的详情信息
 */
func (*DaemonSetService) GetDaemonSetDetail(ctx *gin.Context) {
	daemonSetDetail, err := conf.KuberConfigSet.AppsV1().DaemonSets(ctx.Param("nameSpace")).Get(ctx, ctx.Param("daemonSetName"), metav1.GetOptions{})
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": "获取DaemonSet详情失败",
			"error":   err.Error(),
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"code":       20000,
		"message":    "success",
		"name":       daemonSetDetail.Name,
		"namespace":  daemonSetDetail.Namespace,
		"current":    daemonSetDetail.Status.CurrentNumberScheduled,
		"desired":    daemonSetDetail.Status.DesiredNumberScheduled,
		"ready":      daemonSetDetail.Status.NumberReady,
		"available":  daemonSetDetail.Status.NumberAvailable,
		"conditions": daemonSetDetail.Status.Conditions,
		"labels":     daemonSetDetail.Labels,
	})
}

/*
*	获取DaemonSet列表
 */
func (*DaemonSetService) GetDaemonSetList(ctx *gin.Context) {
	daemonSetList, err := conf.KuberConfigSet.AppsV1().DaemonSets(ctx.Param("nameSpace")).List(ctx, metav1.ListOptions{})
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": "获取DaemonSet列表失败",
			"error":   err.Error(),
		})
		return
	}

	// 简化返回数据，只返回关键信息
	var simplifiedList []gin.H
	for _, daemonSet := range daemonSetList.Items {
		simplifiedList = append(simplifiedList, gin.H{
			"name":      daemonSet.Name,
			"namespace": daemonSet.Namespace,
			"current":   daemonSet.Status.CurrentNumberScheduled,
			"desired":   daemonSet.Status.DesiredNumberScheduled,
			"ready":     daemonSet.Status.NumberReady,
			"available": daemonSet.Status.NumberAvailable,
			"created":   daemonSet.CreationTimestamp,
		})
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":          20000,
		"message":       "success",
		"daemonSetList": simplifiedList,
		"total":         len(daemonSetList.Items),
	})
}

/*
*	创建DaemonSet
 */
func (*DaemonSetService) CreateDaemonSet(ctx *gin.Context) {
	var daemonSetReq DaemonSetRequest

	if err := ctx.ShouldBindJSON(&daemonSetReq); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	daemonSet := createDaemonSetReq2K8s(ctx.Param("nameSpace"), daemonSetReq)
	_, err := conf.KuberConfigSet.AppsV1().DaemonSets(ctx.Param("nameSpace")).Create(ctx, daemonSet, metav1.CreateOptions{})
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": "创建DaemonSet失败",
			"error":   err.Error(),
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":    20000,
		"message": "success",
		"data": gin.H{
			"name":      daemonSetReq.Name,
			"namespace": ctx.Param("nameSpace"),
		},
	})
}

// 转换k8s数据结构
func createDaemonSetReq2K8s(namespace string, req DaemonSetRequest) *appsv1.DaemonSet {
	if req.Labels == nil {
		req.Labels = map[string]string{
			"app": req.Name,
		}
	}

	daemonSet := &appsv1.DaemonSet{
		ObjectMeta: metav1.ObjectMeta{
			Name:      req.Name,
			Namespace: namespace,
			Labels:    req.Labels,
		},
		Spec: appsv1.DaemonSetSpec{
			Selector: &metav1.LabelSelector{
				MatchLabels: req.Labels,
			},
			Template: corev1.PodTemplateSpec{
				ObjectMeta: metav1.ObjectMeta{
					Labels: req.Labels,
				},
				Spec: corev1.PodSpec{
					Containers: []corev1.Container{
						{
							Name:  req.Name,
							Image: req.Image,
							Ports: []corev1.ContainerPort{},
						},
					},
				},
			},
		},
	}

	// 如果指定了端口，添加端口配置
	if req.Port > 0 {
		daemonSet.Spec.Template.Spec.Containers[0].Ports = []corev1.ContainerPort{
			{
				Name:          "http",
				ContainerPort: req.Port,
				Protocol:      corev1.ProtocolTCP,
			},
		}
	}

	return daemonSet
}

/*
*	更新DaemonSet
 */
func (*DaemonSetService) UpdateDaemonSet(ctx *gin.Context) {
	var updateReq struct {
		Image string `json:"image" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&updateReq); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"message": "请求参数错误",
			"error":   err.Error(),
		})
		return
	}

	// 获取现有的DaemonSet
	daemonSet, err := conf.KuberConfigSet.AppsV1().DaemonSets(ctx.Param("nameSpace")).Get(ctx, ctx.Param("daemonSetName"), metav1.GetOptions{})
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": "获取DaemonSet失败",
			"error":   err.Error(),
		})
		return
	}

	// 更新镜像版本
	if len(daemonSet.Spec.Template.Spec.Containers) > 0 {
		daemonSet.Spec.Template.Spec.Containers[0].Image = updateReq.Image
	}

	// 添加更新注释
	if daemonSet.Annotations == nil {
		daemonSet.Annotations = make(map[string]string)
	}
	daemonSet.Annotations["updated-by"] = "kubernate-server"
	daemonSet.Annotations["updated-at"] = metav1.Now().String()

	_, err = conf.KuberConfigSet.AppsV1().DaemonSets(ctx.Param("nameSpace")).Update(ctx, daemonSet, metav1.UpdateOptions{})
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": "更新DaemonSet失败",
			"error":   err.Error(),
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":    20000,
		"message": "success",
		"data": gin.H{
			"name":      daemonSet.Name,
			"namespace": daemonSet.Namespace,
			"image":     updateReq.Image,
		},
	})
}

/*
*	删除DaemonSet
 */
func (*DaemonSetService) DeleteDaemonSet(ctx *gin.Context) {
	deletePolicy := metav1.DeletePropagationForeground
	err := conf.KuberConfigSet.AppsV1().DaemonSets(ctx.Param("nameSpace")).Delete(ctx, ctx.Param("daemonSetName"), metav1.DeleteOptions{
		PropagationPolicy: &deletePolicy,
	})
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"message": "删除DaemonSet失败",
			"error":   err.Error(),
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":    20000,
		"message": "success",
		"data": gin.H{
			"name":      ctx.Param("daemonSetName"),
			"namespace": ctx.Param("nameSpace"),
		},
	})
}
